package routes

import (
	ctrl "gohub/app/http/controllers"
	controllers "gohub/app/http/controllers/api/v1"
	"gohub/app/http/controllers/api/v1/auth"
	"gohub/app/http/middlewares"
	"gohub/app/serve"
	"gohub/pkg/websocket"
	"time"

	"github.com/gin-gonic/gin"
)

// RegisterAPIRoutes 注册网页相关路由
func RegisterAPIRoutes(r *gin.Engine) {
	// admin路由组
	adminGroup := r.Group("/admin")

	// 全局限流中间件：每小时限流。这里是所有 API （根据 IP）请求加起来。
	// 作为参考 Github API 每小时最多 60 个请求（根据 IP）。
	// 测试时，可以调高一点。
	adminGroup.Use(middlewares.LimitIP("200-H"))
	{
		sysGroup := adminGroup.Group("/sys")
		{
			lgc := new(auth.LoginController)
			sysGroup.POST("/login", middlewares.GuestJWT(), lgc.LoginByPassword)

			// 用户模块
			uc := new(controllers.UsersController)
			// 获取当前用户
			sysGroup.GET("/profile", middlewares.AuthJWT(), uc.CurrentUser)
		}

		authGroup := adminGroup.Group("/auth")
		// 限流中间件：每小时限流，作为参考 Github API 每小时最多 60 个请求（根据 IP）
		// 测试时，可以调高一点
		authGroup.Use(middlewares.LimitIP("1000-H"))
		{
			// 注册用户
			suc := new(auth.SignupController)
			authGroup.POST("/signup/phone/exist", middlewares.GuestJWT(), middlewares.LimitPerRoute("60-H"), suc.IsPhoneExist)
			authGroup.POST("/signup/email/exist", middlewares.GuestJWT(), middlewares.LimitPerRoute("60-H"), suc.IsEmailExist)
			authGroup.POST("/signup/using-phone", middlewares.GuestJWT(), suc.SignupUsingPhone)
			authGroup.POST("/signup/using-email", middlewares.GuestJWT(), suc.SignupUsingEmail)

			// 发送验证码
			vcc := new(auth.VerifyCodeController)
			authGroup.POST("/verify-codes/captcha", middlewares.LimitPerRoute("50-H"), vcc.ShowCaptcha)
			authGroup.POST("/verify-codes/phone", middlewares.LimitPerRoute("20-H"), vcc.SendUsingPhone)
			authGroup.POST("/verify-codes/email", middlewares.LimitPerRoute("20-H"), vcc.SendUsingEmail)

			// 登录
			lgc := new(auth.LoginController)
			authGroup.POST("/login/using-phone", middlewares.GuestJWT(), lgc.LoginByPhone)
			authGroup.POST("/sys/login", middlewares.GuestJWT(), lgc.LoginByPassword)
			authGroup.POST("/login/refresh-token", lgc.RefreshToken)

			// 重置密码
			pwc := new(auth.PasswordController)
			authGroup.POST("/password-reset/using-phone", middlewares.GuestJWT(), pwc.ResetByPhone)
			authGroup.POST("/password-reset/using-email", middlewares.GuestJWT(), pwc.ResetByEmail)
		}

		usersGroup := adminGroup.Group("/user")
		{
			// 用户模块
			uc := new(controllers.UsersController)
			cc := new(controllers.ChapterController)
			fc := new(controllers.FeatureController)
			usersGroup.GET("/feature", middlewares.AuthJWT(), fc.Index)
			usersGroup.GET("/chapter", middlewares.AuthJWT(), cc.Index)

			usersGroup.GET("", uc.Index)
			usersGroup.PUT("", middlewares.AuthJWT(), uc.UpdateProfile)
			usersGroup.PUT("/email", middlewares.AuthJWT(), uc.UpdateEmail)
			usersGroup.PUT("/phone", middlewares.AuthJWT(), uc.UpdatePhone)
			usersGroup.PUT("/password", middlewares.AuthJWT(), uc.UpdatePassword)
			usersGroup.PUT("/avatar", middlewares.AuthJWT(), uc.UpdateAvatar)
		}

		chartGroup := adminGroup.Group("/chart")
		{
			cc := new(controllers.ChartController)
			chartGroup.GET("/trend", middlewares.AuthJWT(), cc.Trend)
			chartGroup.GET("/time/amount", middlewares.AuthJWT(), cc.Amount)
			chartGroup.GET("/calendar", middlewares.AuthJWT(), cc.Calendar)
			chartGroup.GET("/pie", middlewares.AuthJWT(), cc.Pie)
			chartGroup.GET("/wordcloud", middlewares.AuthJWT(), cc.Wordcloud)
			chartGroup.GET("/bmap", middlewares.AuthJWT(), cc.Bmap)
			chartGroup.GET("/regions", middlewares.AuthJWT(), cc.Regions)
			chartGroup.GET("/sheets", middlewares.AuthJWT(), cc.Sheets)
		}

		permissionGroup := adminGroup.Group("/permission")
		{
			pc := new(controllers.PermissionController)
			permissionGroup.GET("/list", middlewares.AuthJWT(), pc.Index)
		}

		roleGroup := adminGroup.Group("/role")
		{
			rc := new(controllers.RoleController)
			roleGroup.GET("/list", middlewares.AuthJWT(), rc.Index)
			//pc := new(controllers.PermissionController)
			roleGroup.GET("/permission/:id", middlewares.AuthJWT(), rc.RolePerms)
			roleGroup.POST("/distribute-permission", middlewares.AuthJWT(), rc.SetRolePerms)
		}

		userManageGroup := adminGroup.Group("/user-manage")
		{
			umc := new(controllers.UserManageController)
			userManageGroup.GET("/list", middlewares.AuthJWT(), umc.Index)
			userManageGroup.GET("/role/:id", middlewares.AuthJWT(), umc.GetUserRole)
			userManageGroup.GET("/detail/:id", middlewares.AuthJWT(), umc.GetUserDetail)
			userManageGroup.GET("/delete/:id", middlewares.AuthJWT(), umc.DeleteUser)
			userManageGroup.POST("/update-role/:id", middlewares.AuthJWT(), umc.UpdateUserRole)
			userManageGroup.POST("/update-user/:id", middlewares.AuthJWT(), umc.UpdateUser)
			userManageGroup.POST("/upload", middlewares.AuthJWT(), umc.Upload)
			userManageGroup.POST("/create", middlewares.AuthJWT(), umc.CreateUser)
			userManageGroup.GET("/all-list", middlewares.AuthJWT(), umc.ExportUser)
			userManageGroup.POST("/batch/import", middlewares.AuthJWT(), umc.ImportUser)
		}

		articleGroup := adminGroup.Group("/article")
		{
			ac := new(controllers.ArticleController)
			articleGroup.GET("/list", middlewares.AuthJWT(), ac.Index)
			articleGroup.GET("/:id", middlewares.AuthJWT(), ac.GetArticleDetail)
			articleGroup.POST("/create", middlewares.AuthJWT(), ac.CreateArticle)
		}

		chatGroup := adminGroup.Group("/chat")
		{
			cc := new(controllers.ChatController)
			chatGroup.GET("/completion", middlewares.AuthJWT(), cc.ChatCompletion)
		}
	}
}

// 基础版 ws
func RegisterWsRoute(r *gin.Engine) {
	r.GET("/ws", serve.ServeWebSocket)
}

// WebSocket 管理 + 路由
func SetupWsRouters(r *gin.Engine) {

	// 初始化WebSocket管理器
	wsManager := websocket.NewWebSocketManager()
	wsManager.PingInterval = 15 * time.Second // 自定义心跳间隔
	wsManager.PingTimeout = 35 * time.Second  // 自定义超时时间
	// 启动WebSocket管理器
	go wsManager.Start()

	// 初始化控制器
	wsController := ctrl.NewWebSocketController(wsManager)

	// 建立websocket连接
	r.GET("/ws", wsController.Connect)

	// 发送消息api
	wsGroup := r.Group("/ws")
	{
		wsGroup.POST("/broadcast", wsController.Broadcast)
		wsGroup.POST("/send/client/:client_id", wsController.SendToClient)
		wsGroup.POST("/send/user/:user_id", wsController.SendToUser)
		wsGroup.GET("/clients", wsController.GetClients)
	}
}
